/**
* This file is part of Archiv-Editor.
*
* The software Archiv-Editor serves as a client user interface for working with
* the Person Data Repository. See: pdr.bbaw.de
*
* The software Archiv-Editor was developed at the Berlin-Brandenburg Academy
* of Sciences and Humanities, Jägerstr. 22/23, D-10117 Berlin.
* www.bbaw.de
*
* Copyright (C) 2010-2013 Berlin-Brandenburg Academy
* of Sciences and Humanities
*
* The software Archiv-Editor was developed by @author: Christoph Plutte.
*
* Archiv-Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Archiv-Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Archiv-Editor.
* If not, see <http://www.gnu.org/licenses/lgpl-3.0.html>.
*/
package org.bbaw.pdr.ae.export.xslt.util;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.bbaw.pdr.ae.export.xml.utils.XMLContainer;
import org.w3c.dom.Document;
/**
* Allows to process given XML source with XSLT stylesheet. If no instance of an
* implementation of {@link Result} is given, the result of the last
* transformation is held in a {@link DOMResult} and returned as an
* {@link XMLContainer}.
* <p>All constructors expect the XML input to be passed as a {@link Source}
* implementation. For instance, a {@link StreamSource} representation of an XML
* file can easily be created by calling
* <blockquote><code>new StreamSource(filename);</code></blockquote>
* If the XML content desired to be transformed is embedded in an
* {@link XMLContainer} object, a <code>Source</code> conversion can be fetched
* at {@link XMLContainer#getStream()}.</p>
* <p>Hence the input of a <code>XSLTProcessor</code> can be piped in from
* the same type that its ouput can be send to: {@link XMLContainer}. That way,
* multiple transformations can be conveniently applied in a row.</p>
* <p>The XSL style sheet whished to use for the transformation can also be
* identified by a file name in {@link #XSLTProcessor(Source, String)}.</p>
* @author jhoeper
*/
public class XSLTProcessor
{
/** The tfactory. */
private TransformerFactory _tfactory = null;
/** The source. */
private Source _source = null;
/** The result. */
private Result _result = null;
/** The trans. */
private Transformer _trans = null;
/**
* Creates a new instance of XSLTProcessor by given source and stylesheet. <br/>
* also instantiates the Transformer that applies the XSLT style to the given
* XML input.
* @param src as {@link StreamSource}, {@link DOMSource}, {@link SAXSource}
* @param stylesheet as {@link StreamSource}, {@link DOMSource}, ...
*/
public XSLTProcessor(final Source src, final Source stylesheet)
{
// TODO irgendwo zentral ablegen wegen reuse
_tfactory = TransformerFactory.newInstance();
try
{
_trans = _tfactory.newTransformer(stylesheet);
_source = src;
}
catch (TransformerConfigurationException e)
{
e.printStackTrace();
System.out.println("Transformer could not be initiated");
}
}
/**
* Creates a new instance of XSLT Processor by given source, stylesheet and
* result.
* @param src source
* @param stylesheet style sheet
* @param rslt as implementation of xml.transform.Result
*/
public XSLTProcessor(final Source src, final Source stylesheet, final Result rslt)
{
this(src, stylesheet);
_result = rslt;
}
/**
* Creates a new instance of XSLTProcessor by given source and the name of a
* stylesheet. In detail, creates a {@link StreamSource} for path passed
* with the <code>stylesheetfilename</code> parameter and calls
* the constructor {@link #XSLTProcessor(Source, Source)}.
* @param src A {@link Source} object to read XML input from
* @param stylesheetfilename style sheet filename
*/
public XSLTProcessor(final Source src, final String stylesheetfilename)
{
this(src, new StreamSource(stylesheetfilename));
}
/**
* Processes the XSLT transformation of the XML input on which this
* {@link XSLTProcessor} was instantiated. Since no output resource is
* passed, the result will be stored internally as a {@link DOMResult}
* which can be fetched from {@link #result()}, which for its part converts
* the output to an {@link XMLContainer}.
* @return true if everything went right
*/
public final boolean process()
{
if (_trans != null)
{
if (_result == null)
{
System.out.println("Setting up result object");
_result = new DOMResult();
}
try
{
_trans.transform(_source, _result);
}
catch (TransformerException e)
{
System.out.println("Could not transform");
e.printStackTrace();
return false;
}
return true;
}
else
{
System.out.println("No Transformer instantiated. Was a XSL style sheet loaded?");
return false;
}
}
/**
* processes XML data into given result object.
* @param rslt result
* @return true if it works
*/
public final boolean process(final Result rslt)
{
_result = rslt;
return process();
}
/**
* process XML data into the file of the given name.
* @param resultfilename filename of the result
* @return successful
*/
public final boolean process(final String resultfilename)
{
StreamResult result;
try
{
result = new StreamResult(resultfilename);
}
catch (Exception e)
{
System.out.println("Could not create StreamResult");
return false;
}
return process(result);
}
/**
* Returns a new XMLContainer containing the transformation result. Works
* <b>only if the result is held in a DOMResult instance</b>.
* @return XMLContainer
*/
public final XMLContainer result()
{
XMLContainer xml = null;
if (_result != null)
{
// DOMResult
try
{
xml = new XMLContainer((Document) ((DOMResult) _result).getNode());
}
catch (Exception e)
{
System.out
.println("Could not instantiate XML container for transformation result (Possibly no DOM format)");
e.printStackTrace();
}
return xml;
}
else
{
System.out.println("No result available. Has transformation been conducted?");
return null;
}
}
}